<template>
  <a-form
    v-bind="defaultProps"
    ref="searchFormRef"
    class="search-form">
    <a-row class="search-row">
      <a-col v-for="(formItem, index) in data.conditions" :key="`${formItem.field}-${index}`" :span="formItem.width">
        <a-form-item
          :label="formItem.label"
          :name="formItem.field"
          v-bind="{ ...formItem.props }">
          <component
            v-model:value="modelRef[formItem.field]"
            :form-item="formItem"
            :is="getComponent(formItem.type)"/>
        </a-form-item>
      </a-col>

      <div class="search-btns">
        <a-button type="primary" @click="onSubmit">{{ data.submitText }}</a-button>
        <a-button @click="onCancel">{{ data.cancelText }}</a-button>

        <div class="right-btns">
          <slot name="btns"></slot>
          <a-button type="primary" @click="onAdd">{{ data.addText }}</a-button>
        </div>
      </div>
    </a-row>
  </a-form>  
</template>

<script lang="ts">
import { reactive, toRefs, ref, isReactive, isRef, computed, createVNode, defineComponent, PropType } from 'vue'
import { DataConditions } from './types'
import { Form } from 'ant-design-vue'
import { useForm } from "@ant-design-vue/use"
import components from '@/components/JSON-schema-form/components'

export default defineComponent({
  name: 'search-bar',
  components: {
    ...components,
    [Form.name]: Form,
    [Form.Item.name]: Form.Item
  },
  props: {
    data: {
      type: Object as PropType<DataConditions>,
      default: () => {
        return {}
      }
    },
    tableRef: {
      type: Object
    }
  },
  setup (props) {
    const searchFormRef = ref<any>(null)

    // 生成表单项属性
    const modelRef = reactive(props.data.conditions.reduce((ac, cu) => {
      cu.eventObject ??= {}
      ac[cu.field] = cu.value
      return ac
    }, {}))

    const defaultProps = computed(() => {
      return {
        layout: 'horizontal'
      }
    })

    const preset = ['input', 'textarea', 'select', 'radio', 'checkbox', 'input-number', 'input-range', 'switch']

    // 获取组件名称
    const getComponent = (type) => {
      // 预设组件
      if (preset.includes(type)) {
        return 'schema-form-' + type
      } else if (isReactive(type) || isRef(type)) { // 自定义组件
        return createVNode(type)
      } else { // 不识别组件
        return type
      }
    }

    // 生成表单验证规则
    const rulesRef = reactive(props.data.conditions.filter(item => !item.hidden).reduce((previousValue, currentValue) => {
      currentValue.rules && (previousValue[currentValue.field] = currentValue.rules)
      return previousValue
    }, {}))

    const { resetFields, validate, validateInfos, validateField } = useForm(modelRef, rulesRef);

    console.log('modelRef', modelRef)

    return {
      searchFormRef,
      modelRef,
      defaultProps,
      getComponent,
      validate,
      resetFields,
      validateField,
      validateInfos
    }
  },
  methods: {
    onAdd () {
      this.$emit('add')
    },
    onSubmit () {
      this.$emit('search', this.modelRef)
    },
    onCancel () {
      this.resetFields()
    }
  }
})
</script>

<style lang="less" scoped>
.search-form {
  .search-row {

  }
  .search-btns {
    margin-top: 4px;
    .ant-btn:not(:first-child) {
      margin-left: 8px;
    }
    .right-btns {
      float: right;
      margin-left: 8px;
    }
  }
}
</style>

